/**
 * @author Matan Mizrahi,Chen weissman
 * Introduction to computer science, assingment5
 * Date:2.1.2011
 *
 * a class that represents a variable expression with a name and a value. 
 */
public class VariableExpression  implements Expression,Variable {
    //*********************************Fields************************************//
	private char name;
	
    //*********************************Constructors******************************//
	public VariableExpression(char name){
		this.name=name;
	}
	
    //*********************************Behavior**********************************//
    /**
     * Returns the name of the expression
     * @param   doesn't get any parameters.
     * @return  the char name of the expression
     */
	public char getName(){
		return name;
	}

    /**
     * Return the name of the expression as a string.
     * @param  doesn't get any parameters.
     * @return  the name of the parameter in string type. 
     */		
	public String toString(){
		return name+"";
	}
    /**
     * Indicates whether some other object is equal to this one.
     * @param   "other" the reference object with which to compare.
     * @return  true if this object name is the same as the other name,and returns false otherwise.
     */
     	public boolean equals(Object other){
		boolean ans=false;
		if (other == null)
			throw new NullPointerException("The variable you want to equlize can't be Null.");
		else if (other instanceof VariableExpression){
				VariableExpression newOther=(VariableExpression)other;
				if (this.name==newOther.name);
					ans=true;
			}
		else throw new RuntimeException("The answer is false,because you tried to equalize an " +
		"object that is not from the type VariableExpression.");
		return ans;
	}
	
    /**
     * Returns the symbol of the last operation that has been done.
     * @param   doesn't get any parameters.
     * @return  the symbol of the last operation as a string.
     * @throws Exception in case the assignment is null or if the variable is not assigned to a value
     */
	public double evaluate(Assignment assign) throws Exception{
		double ans=0;
		if (assign ==null)
			throw new NullPointerException("The evaluate method at VariableExpression has got a null argument");
		else
			if (assign.getVarValue(name)!=null)
				ans=assign.getVarValue(name);
		if (assign.getVarValue(name)== null) throw new Exception("The variable was not assigned  to a value");
		return ans;
	}
    /**
     * Returns the derivative of a given number
     * @param   "var" double number to derive.
     * @return  always return an object from the type Constant.If the the derivation is on the 
     * current number the result is constant with value 1, otherwise the result is constant
     * with the value 0 
     */
	public Expression derivative(char name){
		Expression ans;
		if (name==this.name) 
			ans= new Constant(1);
		else 
			ans= new Constant(0);
		return ans;
	}

/**
 * Replicating the invoking VariableExpression.
 * 
 * @return a replicate of this VariableExpression. The returned VariableExpression has
 * to be a new object (with a different address than this
 * object), but equivalent to the this VariableExpression under the 
 * application of the {@code equals(Object other)} method.
 */
	public Expression replicate(){
		return new VariableExpression(this.name);
	}
}
